package com.veepeak.server.service;

import com.veepeak.server.common.BaseRepository;
import com.veepeak.server.common.BaseService;
import com.veepeak.server.common.DateUtils;
import com.veepeak.server.domain.*;
import com.veepeak.server.repository.UserRepository;
import net.bytebuddy.asm.Advice;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.internet.MimeMessage;
import java.util.Optional;
import java.util.UUID;

@Service
public class UserService extends BaseService<User, String> {
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private RegistVerifyService registVerifyService;
    @Autowired
    private VehicleService vehicleService;
    @Autowired
    private UserVehicleService userVehicleService;
    @Autowired
    private ObdService obdService;
    @Autowired
    private UserObdService userObdService;
    @Autowired
    private JavaMailSender mailSender;

    @Override
    public BaseRepository<User, String> getRepo() {
        return this.userRepository;
    }

    /**
     * 重置密码时获取验证码
     */
    public String resetPasswordEmailVerifyCode(String email) throws Exception {
        String verifyCode = UUID.randomUUID().toString().replace("-","").substring(0,6).toLowerCase();
        User user = userRepository.getFirstByEmail(email);
        if ( user != null) {
            user.setEmailValidateCode(verifyCode);
            user.setEmailValidateCodeTime(DateUtils.getDateTime());
            userRepository.save(user);

            MimeMessage mimeMessage = this.mailSender.createMimeMessage();
            MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
            message.setFrom("53255941@qq.com");//设置发信人，发信人需要和spring.mail.username配置的一样否则报错
            message.setTo(email);                //设置收信人
            message.setSubject("重置密码的验证码");    //设置主题
            message.setText("<h1>"+user.getEmailValidateCode()+"</h1>", true);    //第二个参数true表示使用HTML语言来编写邮件
            this.mailSender.send(mimeMessage);
            return verifyCode;
        } else {
            throw new RuntimeException("email error");
        }
    }

    /**
     * 重置密码
     */
    public User resetPassword(String email,String newPassword,String verifyCode){
        User user = userRepository.getFirstByEmail(email);
        if ( user != null) {
            if ( !user.getEmailValidateCode().equals(verifyCode) ){
                throw new RuntimeException("code error");
            }
            user.setPassword(newPassword);
            userRepository.save(user);
            return user;
        }else{
            throw new RuntimeException("user not exist");
        }
    }

    /**
     * 修改密码
     */
    public User editPassword(String email,String oldPassword, String newPassword){
        User user = userRepository.getFirstByEmailAndPassword(email,oldPassword);
        if ( user == null ){
            throw new RuntimeException("email or password error");
        }

        user.setPassword(newPassword);
        userRepository.save(user);
        return user;
    }

    /**
     * 注册时获取验证码
     */
    public String emailVerifyCode(String email) throws Exception {
        String verifyCode = UUID.randomUUID().toString().replace("-","").substring(0,6).toLowerCase();
        User user = userRepository.getFirstByEmail(email);
        if ( user != null ){
            throw new RuntimeException("email existed!");
        }else{
            MimeMessage mimeMessage = this.mailSender.createMimeMessage();
            MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
            message.setFrom("appsupport@veepeak.com");//设置发信人，发信人需要和spring.mail.username配置的一样否则报错
            message.setTo(email);                //设置收信人
            message.setSubject("Veepeak OBD APP register code ");    //设置主题
            message.setText("<h1> Your register code is : "+verifyCode+"</h1>", true);    //第二个参数true表示使用HTML语言来编写邮件
            this.mailSender.send(mimeMessage);

            RegistVerify registVerify = new RegistVerify();
            registVerify.setEmail(email);
            registVerify.setVerifyCode(verifyCode);
            registVerify.setCreateDate(DateUtils.getDateTime());
            registVerifyService.save(registVerify);
            return verifyCode;
        }
    }

    public User login(String email, String password) {
        User user = userRepository.getFirstByEmailAndPassword(email, password);
        return user;
    }

    public User regist(String email, String password,String registVerifyCode) {

//        RegistVerify exampleVerifyCode = new RegistVerify();
//        exampleVerifyCode.setVerifyCode(registVerifyCode);
//        Optional<RegistVerify> optionalRegistVerify = registVerifyService.get(Example.of(exampleVerifyCode));
//        if ( !optionalRegistVerify.isPresent() ){
//            throw new RuntimeException("verify code error");
//        }

        User user = userRepository.getFirstByEmail(email);
        if ( user != null ){
            throw new RuntimeException("email existed");
        }else{
            user = new User();
            user.setEmail(email);
            user.setPassword(password);
            user.setEmailValidateCode(registVerifyCode);
//            user.setEmailValidateCodeTime(optionalRegistVerify.get().getCreateDate());
            user.setEmailValidated(true);
            return save(user);
        }


    }


    public UserVehicle setVehicle(String userId, String name, String year, String modelId) {
        User user = get(userId);
        if ( user == null ){
            throw new RuntimeException("user not existed");
        }
        Vehicle vehicle = new Vehicle();
        vehicle.setName(name);
        vehicle.setYear(year);
        vehicle.setModel(vehicleService.getModelById(modelId));
        vehicleService.save(vehicle);

        UserVehicle userVehicle = new UserVehicle();
        userVehicle.setUser(user);
        userVehicle.setVehicle(vehicle);
        userVehicleService.save(userVehicle);

        return userVehicle;
    }

    public void removeVehicle(String userId, String vehicleId) {
        User user = get(userId);
        if ( user == null ){
            throw new RuntimeException("user not existed");
        }
        Vehicle vehicle = vehicleService.get(vehicleId);
        if ( vehicle == null ){
            throw new RuntimeException("vehicle not existed");
        }

        userVehicleService.deleteByUserIdAndVehicleId(userId,vehicleId);
        vehicleService.delete(vehicleId);
    }

    public Vehicle editVehicle(String vehicleId, String name, String year, String modelId) {
        Vehicle vehicle = vehicleService.get(vehicleId);
        if ( vehicle == null ){
            throw new RuntimeException("vehicle not existed");
        }
        vehicle.setName(name);
        vehicle.setYear(year);
        vehicle.setModel(vehicleService.getModelById(modelId));
        vehicleService.save(vehicle);
        return vehicle;
    }

    public UserObd setObd(String userId, String obdModel, String bluetoothAddress,String bluetoothName) {
        User user = get(userId);
        if ( user == null ){
            throw new RuntimeException("user not existed");
        }

        UserObd userObd = new UserObd();
        userObd.setUser(user);
        userObd.setObdModel(obdModel);
        userObd.setBluetoothAddress(bluetoothAddress);
        userObd.setBluetoothName(bluetoothName);
        userObd.setBindTime(DateUtils.getDateTime());

        userObdService.save(userObd);

        return userObd;
    }

    public void removeObd(String userObdId) {
        userObdService.deleteById(userObdId);
    }

    public Obd editObd(String obdId, String serialsNumber, String productModel) {
        Obd obd = obdService.get(obdId);
        if ( obd == null ){
            throw new RuntimeException("obd not existed");
        }
        obd.setSerialsNumber(serialsNumber);
        obd.setProductModel(productModel);
        obdService.save(obd);
        return obd;
    }

    public User editNickname(String userId, String nickname) {
        User user = userRepository.getOne(userId);
        if ( user == null ){
            throw new RuntimeException("user not existed");
        }
        if (StringUtils.isBlank(nickname)){
            throw new RuntimeException("nickname is null");
        }
        user.setNickname(nickname);
        userRepository.save(user);
        return user ;
    }

    public Page<User> datatables(int page, int size, String searchValue){
        if ( StringUtils.isBlank(searchValue)){
            return userRepository.findAll(PageRequest.of(page,size));
        }else{
            return userRepository.findByEmailIsLike(PageRequest.of(page,size),"%"+searchValue+"%");
        }
    }
}
